package com.mc.lp.database.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.mc.lp.database.dao.IAttachmentDAO;
import com.mc.lp.database.dao.IMicroCampusEntityDAO;
import com.mc.lp.database.entity.AttachmentEntity;
import com.mc.lp.database.entity.MicroCampusEntity;
import com.mc.lp.database.entity.helper.AttachmentEntityHelper;
import com.mc.lp.database.entity.helper.MicroCampusHelper;
import com.mc.lp.database.entity.type.RecordType;
import com.mc.lp.database.service.IAttachmentService;
import com.mc.lp.service.MicroCampusAbstractService;
import com.mc.lp.shared.util.constants.ResponseStatus;
import com.mc.lp.shared.vo.AttachmentVO;
import com.mc.lp.shared.vo.FileVo;
import com.mc.lp.shared.vo.SearchCriteriaVO;
import com.mc.lp.shared.vo.ServiceResponse;
import com.mc.lp.shared.vo.StudentProfileVO;
import com.mc.lp.shared.vo.ValueObjectList;

@Service
public class AttachmentServiceImpl extends MicroCampusAbstractService<AttachmentServiceImpl> implements IAttachmentService {

	@Resource
	IAttachmentDAO attachmentDAO;

	@Resource
	IMicroCampusEntityDAO microCampusEntityDAO;
	
	Logger logger = Logger.getLogger(AttachmentServiceImpl.class);

	@Transactional
	public ServiceResponse<FileVo> deleteAttachment(Long id) {
		attachmentDAO.deleteAttachment(id);
		ServiceResponse<FileVo> serviceresponse = new ServiceResponse<FileVo>();
		serviceresponse.setMsg("Deleted Successfully.");
		serviceresponse.setStatus(ResponseStatus.SUCCESS);
		serviceresponse.setResult(Arrays.asList(new FileVo(id, "", null)));
		return serviceresponse;
	}

	@Transactional
	public ServiceResponse<FileVo> saveAttachment(AttachmentVO attachmentVo) {
		try {
			if (attachmentVo.getFile().getData().getBytes().length / (1024 * 1024) > 4) {
				ServiceResponse<FileVo> serviceresponse = new ServiceResponse<FileVo>();
				serviceresponse.setMsg("File Size is too big");
				serviceresponse.setStatus(ResponseStatus.FAILED);
				getLogger().error("Error in attaching file because of high size");
				return serviceresponse;
			}
		} catch (Exception e) {
			getLogger().error("Error in attaching file",e);
			ServiceResponse<FileVo> serviceresponse = new ServiceResponse<FileVo>();
			serviceresponse.setMsg("Error in attaching file");
			serviceresponse.setStatus(ResponseStatus.FAILED);
			return serviceresponse;
		}

		Date startTime = new Date(); 
		System.out.println("Attachment save Started " + startTime.getTime());
		AttachmentEntityHelper helper = new AttachmentEntityHelper();
		MicroCampusHelper entityHelper = new MicroCampusHelper();
		MicroCampusEntity microCampusEntity = microCampusEntityDAO.get(attachmentVo.getStudentEntityId());
		StudentProfileVO vo = entityHelper.getVO(microCampusEntity);
		AttachmentEntity attachEntity;
		if (attachmentVo.getRecordType().equals(RecordType.PROFILE_PIC)) {
			if (null != vo.getPhotoId()) {
				attachEntity = attachmentDAO.get(vo.getPhotoId());
			} else {
				attachEntity = new AttachmentEntity();
			}
		} else {

			if (null != attachmentVo.getFile() && null != attachmentVo.getFile().getId()) {
				attachEntity = attachmentDAO.get(attachmentVo.getFile().getId());
			} else {
				attachEntity = new AttachmentEntity();
			}

		}

		helper.setEntity(attachmentVo, attachEntity);
		attachEntity.setEntityId(microCampusEntity);
		attachmentDAO.saveAttachment(attachEntity,attachmentVo.getFile());
		

		FileVo newFile = new FileVo(attachEntity.getId(), attachEntity.getName(), null);
		ServiceResponse<FileVo> serviceresponse = new ServiceResponse<FileVo>();
		serviceresponse.setMsg("Saved Successfully.");
		serviceresponse.setStatus(ResponseStatus.SUCCESS);
		ArrayList<FileVo> files = new ArrayList<FileVo>();
		files.add(newFile);
		serviceresponse.setResult(files);
		
		Date endTime = new Date(); 
		
		System.out.println("Attachment save Started "+endTime.getTime());
		System.out.println("Attachent size "+(attachmentVo.getFile().getData().getBytes().length / (1024 * 1024)));
		System.out.println("***************************** TOTAL TIME FOR SAVING ATTACHMENT "+(endTime.getTime()-startTime.getTime()));
		return serviceresponse;
	}

	@Transactional
	public ValueObjectList getAttachmentsWithoutData(SearchCriteriaVO searchCriteria) {
		List<AttachmentEntity> entityList = attachmentDAO.fetchAttachmentWithoutData(searchCriteria);
		ValueObjectList list = new ValueObjectList();
		for (AttachmentEntity ae : entityList) {
			FileVo vo = new FileVo(ae.getId(), ae.getName(), null);
			list.add(vo);
		}
		return list;
	}

	@Transactional
	public FileVo downloadAttachmentWithData(Long id) {
		AttachmentEntity en = attachmentDAO.get(id);
		FileVo vo = null;
		try {
			byte[] fileData;
			fileData = en.getData().getBytes(1, (int) en.getData().length());
			vo = new FileVo(id, en.getName(), new String(fileData));
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error("Error in Download attachment ", e);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("Error in Download attachment ", e);
		}
		return vo;
	}

	@Transactional
	public FileVo getAttachmentByRecordTypeAndIdentifiers(Long entityId, Long recordId, RecordType recordType) {
		AttachmentEntity en = attachmentDAO.getAttachmentByRecordTypeAndIdentifiers(entityId, recordId, recordType);
		FileVo vo = null;
		try {
			byte[] fileData;
			fileData = en.getData().getBytes(1, (int) en.getData().length());
			vo = new FileVo(en.getId(), en.getName(), new String(fileData));
		} catch (Exception e) {

		}
		return vo;
	}

	@Transactional
	public List<AttachmentVO> getAttachmentsByGrade(Long entityId, Integer grade, RecordType recordType, boolean isDataRequired) {

		List<AttachmentVO> voList = new ArrayList<AttachmentVO>();

		List<AttachmentEntity> attachList = attachmentDAO.fetchAttachmentsByGrade(entityId, grade, recordType, isDataRequired);
		AttachmentEntityHelper helper = new AttachmentEntityHelper();
		for (AttachmentEntity attachmentEntity : attachList) {
			voList.add(helper.getVO(attachmentEntity));
		}

		return voList;
	}

}